1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect.testing.testers;
18  
19  import static com.google.common.collect.testing.features.CollectionSize.ONE;
20  import static com.google.common.collect.testing.features.CollectionSize.ZERO;
21  import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
22  import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
23  import static com.google.common.collect.testing.features.MapFeature.REJECTS_DUPLICATES_AT_CREATION;
24  
25  import com.google.common.annotations.GwtCompatible;
26  import com.google.common.collect.testing.AbstractMapTester;
27  import com.google.common.collect.testing.features.CollectionSize;
28  import com.google.common.collect.testing.features.MapFeature;
29  
30  import java.util.Arrays;
31  import java.util.List;
32  import java.util.Map.Entry;
33  
34  /**
35   * A generic JUnit test which tests creation (typically through a constructor or
36   * static factory method) of a map. Can't be invoked directly; please see
37   * {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
38   *
39   * @author Chris Povirk
40   * @author Kevin Bourrillion
41   */
42  @GwtCompatible(emulated = true)
43  public class MapCreationTester<K, V> extends AbstractMapTester<K, V> {
44    @MapFeature.Require(ALLOWS_NULL_KEYS)
45    @CollectionSize.Require(absent = ZERO)
46    public void testCreateWithNullKeySupported() {
47      initMapWithNullKey();
48      expectContents(createArrayWithNullKey());
49    }
50  
51    @MapFeature.Require(absent = ALLOWS_NULL_KEYS)
52    @CollectionSize.Require(absent = ZERO)
53    public void testCreateWithNullKeyUnsupported() {
54      try {
55        initMapWithNullKey();
56        fail("Creating a map containing a null key should fail");
57      } catch (NullPointerException expected) {
58      }
59    }
60  
61    @MapFeature.Require(ALLOWS_NULL_VALUES)
62    @CollectionSize.Require(absent = ZERO)
63    public void testCreateWithNullValueSupported() {
64      initMapWithNullValue();
65      expectContents(createArrayWithNullValue());
66    }
67  
68    @MapFeature.Require(absent = ALLOWS_NULL_VALUES)
69    @CollectionSize.Require(absent = ZERO)
70    public void testCreateWithNullValueUnsupported() {
71      try {
72        initMapWithNullValue();
73        fail("Creating a map containing a null value should fail");
74      } catch (NullPointerException expected) {
75      }
76    }
77  
78    @MapFeature.Require({ALLOWS_NULL_KEYS, ALLOWS_NULL_VALUES})
79    @CollectionSize.Require(absent = ZERO)
80    public void testCreateWithNullKeyAndValueSupported() {
81      Entry<K, V>[] entries = createSamplesArray();
82      entries[getNullLocation()] = entry(null, null);
83      resetMap(entries);
84      expectContents(entries);
85    }
86  
87    @MapFeature.Require(value = ALLOWS_NULL_KEYS,
88        absent = REJECTS_DUPLICATES_AT_CREATION)
89    @CollectionSize.Require(absent = {ZERO, ONE})
90    public void testCreateWithDuplicates_nullDuplicatesNotRejected() {
91      expectFirstRemoved(getEntriesMultipleNullKeys());
92    }
93  
94    @MapFeature.Require(absent = REJECTS_DUPLICATES_AT_CREATION)
95    @CollectionSize.Require(absent = {ZERO, ONE})
96    public void testCreateWithDuplicates_nonNullDuplicatesNotRejected() {
97      expectFirstRemoved(getEntriesMultipleNonNullKeys());
98    }
99  
100   @MapFeature.Require({ALLOWS_NULL_KEYS, REJECTS_DUPLICATES_AT_CREATION})
101   @CollectionSize.Require(absent = {ZERO, ONE})
102   public void testCreateWithDuplicates_nullDuplicatesRejected() {
103     Entry<K, V>[] entries = getEntriesMultipleNullKeys();
104     try {
105       resetMap(entries);
106       fail("Should reject duplicate null elements at creation");
107     } catch (IllegalArgumentException expected) {
108     }
109   }
110 
111   @MapFeature.Require(REJECTS_DUPLICATES_AT_CREATION)
112   @CollectionSize.Require(absent = {ZERO, ONE})
113   public void testCreateWithDuplicates_nonNullDuplicatesRejected() {
114     Entry<K, V>[] entries = getEntriesMultipleNonNullKeys();
115     try {
116       resetMap(entries);
117       fail("Should reject duplicate non-null elements at creation");
118     } catch (IllegalArgumentException expected) {
119     }
120   }
121 
122   private Entry<K, V>[] getEntriesMultipleNullKeys() {
123     Entry<K, V>[] entries = createArrayWithNullKey();
124     entries[0] = entry(null, entries[0].getValue());
125     return entries;
126   }
127 
128   private Entry<K, V>[] getEntriesMultipleNonNullKeys() {
129     Entry<K, V>[] entries = createSamplesArray();
130     entries[0] = entry(samples.e1.getKey(), samples.e0.getValue());
131     return entries;
132   }
133 
134   private void expectFirstRemoved(Entry<K, V>[] entries) {
135     resetMap(entries);
136 
137     List<Entry<K, V>> expectedWithDuplicateRemoved =
138         Arrays.asList(entries).subList(1, getNumElements());
139     expectContents(expectedWithDuplicateRemoved);
140   }
141 }
142